Skip to content

feat(copilot): let the mothership manage workspace sandboxes - #6239

Closed
waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-sandbox-crud-tools
Closed

waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-sandbox-crud-tools

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Adds the sim-side handler for the new manage_sandbox mothership tool, so agents can create, edit, delete, and list a workspace's sandboxes — the named dependency sets Function blocks import third-party packages from. Previously these could only be managed in Settings > Sandboxes.

Companion: https://github.com/simstudioai/mothership/pull/395

Follows the manage_custom_tool / manage_mcp_tool / manage_skill precedent: handler under lib/copilot/tools/handlers/management/, wired through register-handlers.ts, title in tool-display.ts, icon in the chat tool-icon map.

Sandbox writes are gated exactly as the REST routes gate them — workspace admin, then the Max/Enterprise entitlement, then the same per-workspace mutation bucket — so chat cannot create a sandbox the same user could not create in the UI. workspaceId comes from server context only, never from the model.

Create/update/delete moved out of the two route files into workspace-sandboxes.ts as shared operations returning a typed failure that each caller renders for its own surface: the routes map it to 409/400/404, the tool to a sentence. The routes previously owned the name-conflict pre-check, the unique-index race catch, the unconditional build enqueue, and the detached image release — sharing them is what stops the tool drifting from the UI.

Type of Change

  • New feature

Testing

  • 127 test files / 1516 tests pass across lib/copilot, lib/execution/remote-sandbox, and app/api/workspaces
  • New: 19 handler tests (auth, entitlement, rate limit, per-operation validation) and 8 operations tests
  • tsc --noEmit clean; lint:check 23/23 (the 9 warnings are pre-existing in zoho-desk.test.ts)
  • check:api-validation:strict, check:boundaries, check:utils, check:client-boundary, check:tool-registry-boundary all pass

Reviewers should focus on the permission gate in manage-sandbox.ts and the name/dependency validation in workspace-sandboxes.ts.

One real bug was found and fixed during review: updateWorkspaceSandbox treated a whitespace-only name as supplied, so it trimmed to empty, skipped the (falsy) conflict pre-check, and wrote an unnamed sandbox the UI cannot produce. Name validation now reuses the contract's own sandboxNameSchema, so the tool path — which has no schema in front of it — cannot accept a name the REST path rejects. The regression test was confirmed to fail against the original code.

Not yet exercised against a live mothership turn; the natural check is asking Sim to add a Python sandbox with requests and confirming it appears in Settings > Sandboxes with a build status.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Adds the manage_sandbox handler (add/edit/delete/list), following the
manage_custom_tool precedent, plus the display title and generated
catalog bindings.

Sandbox create/update/delete moves out of the two REST route files into
workspace-sandboxes.ts as createWorkspaceSandbox/updateWorkspaceSandbox/
deleteWorkspaceSandbox, returning a typed failure the caller renders for
its own surface: the routes map it to 409/400/404, the tool to a
sentence. The routes previously owned the name-conflict pre-check, the
unique-index race catch, the unconditional build enqueue, and the
detached image release; sharing them is what keeps the tool from
drifting from the UI.

The handler reproduces the routes' gate exactly — workspace admin, then
the Max/Enterprise entitlement, then the same per-workspace mutation
bucket — so a sandbox cannot be created through chat that the same user
could not create in Settings > Sandboxes. `list` needs only read access,
matching GET, because a downgraded workspace must still see what it
built. workspaceId comes from server context only.
Fixes found auditing the first pass:

- updateWorkspaceSandbox treated a whitespace-only name as supplied, so it
  trimmed to empty, skipped the falsy conflict pre-check, and wrote an
  unnamed sandbox the UI cannot produce. Name normalization now runs in the
  operations layer and reuses the contract's own sandboxNameSchema, so the
  tool path — which has no schema in front of it — cannot accept a name the
  REST path rejects.
- The handler resolved permissions through ensureWorkspaceAccess while the
  route used getUserEntityPermissions, so the same refusal was worded two
  ways. Both now use the same primitive and the same SANDBOX_ADMIN_REQUIRED
  constant, and a DB failure no longer reads as a permission denial.
- list returned errorDetail, a 4KB installer log tail per failed build, on
  every call. errorMessage is the classified summary and is all the tool
  prompt advertises.
- buildSpecUpdate now returns a result instead of throwing, dropping the
  SandboxDependencyError class, the rethrowing bridge helper, and both
  try/catch blocks.
- Model-supplied dependencies are type-checked once before dispatch rather
  than per branch; the language error copy derives from SANDBOX_LANGUAGES.
- Create logging moved into the operations layer so the tool's creates are
  logged too, and the route no longer carries a logger.
- manage_sandbox was missing from the chat tool-icon map and fell through to
  the mothership Blimp fallback.
- Gate writes with copilotToolCanAdmin(context.userPermission), the admin
  sibling of the copilotToolCanWrite helper manage_custom_tool and manage_skill
  already use, instead of a second DB permission read. The tool now declares
  RequiredPermission "write", so the executor has already resolved the caller's
  permission by the time the handler runs.
- Trim comments that restated the code, per the family's near-zero density.
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 4, 2026 3:56am

Request Review

@cursor

cursor Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches sandbox authoring (build scheduling, image release, name conflicts) on a shared code path used by both UI and copilot; permission and entitlement gates are mirrored but worth verifying on write operations.

Overview
Adds the manage_sandbox copilot tool so agents can list, create, edit, and delete workspace sandboxes (dependency sets for Function blocks), matching what Settings > Sandboxes already allows. Writes use the same gates as the REST API: workspace admin, Max/Enterprise entitlement, and the shared mutation rate limit; workspaceId is taken only from server context, not model args.

Sandbox create/update/delete logic is moved out of the API route handlers into workspace-sandboxes.ts, returning typed SandboxWriteFailure results. Routes map those to HTTP via sandboxFailureResponse; the tool maps them to user-facing strings. Name rules reuse exported sandboxNameSchema so the tool cannot accept names the REST contract would reject (including the whitespace-only name bug on edit).

Also wires copilotToolCanAdmin, tool catalog/schemas, handler registration, chat display titles/icons, and tests for the handler and shared operations.

Reviewed by Cursor Bugbot for commit df6159d. Configure here.

@github-actions github-actions Bot added the requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

⚠️ Cross-repo companion check

One or more companion PRs aren't merged into staging yet. Merging this without them will leave copilot and sim out of sync — merge them in lockstep.

  • ❌ simstudioai/mothership#395 — OPEN, not merged (targets staging) — feat(tools): manage_sandbox — CRUD for workspace sandboxes

@greptile-apps

greptile-apps Bot commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds Copilot support for listing and managing workspace sandboxes while consolidating REST and Copilot mutations behind shared operations.

  • Registers and displays the new manage_sandbox tool.
  • Enforces server-derived workspace scope, admin authorization, plan entitlement, and workspace mutation limits.
  • Extracts validated create, update, and delete behavior into shared workspace-sandbox operations.
  • Preserves REST-specific failure responses and adds handler and operation coverage.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported listing restriction was explicitly confirmed as intentional and consistent with the established management-tool permission model.

Important Files Changed

Filename Overview
apps/sim/lib/copilot/tools/handlers/management/manage-sandbox.ts Implements the Copilot-facing list and mutation handler with server-scoped workspace access and REST-equivalent mutation gates.
apps/sim/lib/execution/remote-sandbox/workspace-sandboxes.ts Centralizes validated sandbox creation, update, deletion, build scheduling, cache invalidation, and typed failures.
apps/sim/app/api/workspaces/[id]/sandboxes/route.ts Refactors collection routes to delegate sandbox creation and listing authorization to shared operations.
apps/sim/app/api/workspaces/[id]/sandboxes/[sandboxId]/route.ts Refactors update and delete routes to use the shared mutation operations and failure mapping.
apps/sim/lib/copilot/generated/tool-catalog-v1.ts Registers the new asynchronous management tool with the same intentional tool-wide write gate used by sibling management tools.

Sequence Diagram

sequenceDiagram
  participant Model as Copilot
  participant Exec as Tool Executor
  participant Handler as manage_sandbox
  participant Gate as Auth/Billing/Rate Limit
  participant Ops as Workspace Sandbox Operations
  participant DB as Database
  participant Registry as Image Registry

  Model->>Exec: manage_sandbox(operation, arguments)
  Exec->>Exec: Enforce catalog write permission
  Exec->>Handler: Server execution context
  alt list
    Handler->>Ops: listWorkspaceSandboxes(workspaceId)
    Ops->>DB: Read workspace sandboxes
    DB-->>Ops: Sandbox rows
    Ops-->>Handler: Sandboxes
    Handler-->>Model: Sanitized list
  else add/edit/delete
    Handler->>Gate: Require admin, entitlement, mutation budget
    Gate-->>Handler: Allowed
    Handler->>Ops: Shared mutation(workspaceId, arguments)
    Ops->>DB: Validate and persist
    Ops->>Registry: Schedule/release image as needed
    Ops-->>Handler: Sandbox or typed failure
    Handler-->>Model: Tool-specific result
  end
Loading

Reviews (2): Last reviewed commit: "refactor(copilot): align manage_sandbox ..." | Re-trigger Greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit df6159d. Configure here.

@waleedlatif1
waleedlatif1 deleted the worktree-sandbox-crud-tools branch September 5, 2026 23:03

This branch was previously deployed

1 inactive deployment
Preview — df6159dc Deployed Aug 4, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant